home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
ldb.zip
/
BINDER.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
13KB
|
685 lines
/*
binder.cpp
10-18-91
Loose Data Binder v 1.4
Copyright 1991
John W. Small
All rights reserved
PSW / Power SoftWare
P.O. Box 10072
McLean, Virginia 22102 8072 USA
John Small
Voice: (703) 759-3838
CIS: 73757,2233
*/
#include <string.h>
#include "binder.hpp"
void Binder::construct(unsigned flags, unsigned maxNodes,
unsigned limit, unsigned delta)
{
curNode = first = nodes = 0;
comparE = BDRcomparE0;
/*
The following relationships are maintained
during operation of a binder:
1 <= delta <= lowLimit <= limit <= maxNodes
<= BDR_MAXNODES
lowThreshold = lowLimit - delta;
*/
if (maxNodes > BDR_MAXNODES)
maxNodes = BDR_MAXNODES;
if (limit > maxNodes)
limit = maxNodes;
if (delta > limit)
delta = limit;
if (!delta) {
delta = 1;
if (limit < delta)
limit = delta;
if (maxNodes < limit)
maxNodes = limit;
}
if ((linkS = new voiD[limit]) == voiDV0)
this->limit = lowLimit = lowThreshold
= this->delta = this->maxNodes
= this->flags = 0;
else {
this->limit = limit;
this->delta = delta;
this->maxNodes = maxNodes;
lowLimit = limit;
lowThreshold = lowLimit - delta;
this->flags = ((flags & BDR_OK_FREE)
| BDR_SORTED);
}
}
Binder::Binder(voiDV argv, int argc, unsigned flags)
{
construct(flags,BDR_MAXNODES,argc,BDR_DELTA);
if (argv) if (argc > 0)
while (argc--)
push(argv[argc]);
else
for (argc = 0; insQ(argv[argc]); argc++);
}
voiDV Binder::vector()
{
voiDV V = voiDV0;
if (nodes) if ((V = new voiD[nodes+1]) != voiDV0) {
for (unsigned i = 0; i < nodes; i++)
V[i] = atGet(i);
V[i] = voiD0;
}
return V;
}
Binder::~Binder()
{
if (flags & BDR_OK_FREE)
allFree();
else
allDel();
if (linkS)
delete linkS;
}
unsigned Binder::setLimit(unsigned newLimit)
{
voiDV newLinkS;
unsigned i;
if (newLimit < nodes)
newLimit = nodes;
else if (newLimit > maxNodes)
newLimit = maxNodes;
if (newLimit < delta)
newLimit = delta;
if (!linkS || !newLimit || newLimit == limit)
return 0;
if ((newLinkS = new voiD[newLimit]) == voiDV0)
return 0;
if ((i = limit - first) > nodes)
i = nodes;
memcpy(newLinkS,&linkS[first],sizeof(linkS[0])*i);
/* copy wrap around */
if (i < nodes)
memcpy(&newLinkS[i],linkS,
sizeof(linkS[0])*(nodes-i));
if (newLimit > limit)
if (newLimit - delta > limit)
lowLimit = newLimit - delta;
else
lowLimit = limit;
else
if (newLimit - delta > delta)
lowLimit = newLimit - delta;
else
lowLimit = delta;
lowThreshold = lowLimit - delta;
delete linkS;
linkS = newLinkS;
limit = newLimit;
first = 0;
return limit;
}
unsigned Binder::setDelta(unsigned newDelta)
{
return ((newDelta && newDelta <= lowLimit)?
delta = newDelta : 0);
}
unsigned Binder::setMaxNodes(unsigned newMaxNodes)
{
return ((newMaxNodes >= limit)?
(maxNodes = (newMaxNodes
> BDR_MAXNODES)? BDR_MAXNODES
: newMaxNodes) : 0);
}
voiD Binder::atIns(unsigned n, const voiD D)
{
voiDV newLinkS;
unsigned newLimit, i;
if (!linkS || !D)
return voiD0;
if (nodes == limit) {
if (limit == maxNodes)
return voiD0;
newLimit = (maxNodes - delta > limit)?
limit + delta : maxNodes;
if ((newLinkS = new voiD[newLimit])
== voiDV0) return voiD0;
if ((i = limit - first) > nodes)
i = nodes;
memcpy(newLinkS,&linkS[first],
sizeof(linkS[0])*i);
/* copy wrap around */
if (i < nodes)
memcpy(&newLinkS[i],linkS,
sizeof(linkS[0])*(nodes-i));
/*
Compute next smaller linkS size
and threshold for shrinking.
*/
lowLimit = limit;
lowThreshold = lowLimit - delta;
/* swap new for old */
delete linkS;
linkS = newLinkS;
limit = newLimit;
first = 0;
}
if (!Dattach(D))
return voiD0;
if (!n) /* push */
linkS[first? --first
: (first = limit - 1)] = D;
else if (n >= nodes) /* insQ */
linkS[(first+(n=nodes))%limit] = D;
else { /* insert interior */
i = (first + n) % limit;
if (i < first || !first)
/* move rear rightward */
memmove(&linkS[i+1],&linkS[i],
sizeof(linkS[0])
* (nodes-n));
else /* move front leftward */
memmove(&linkS[--first],&linkS[--i],
sizeof(linkS[0])*(n+1));
linkS[i] = D;
}
nodes++;
if (n <= curNode)
curNode++;
flags &= ~BDR_SORTED;
return D;
}
voiD Binder::atDel(unsigned n)
{
voiDV newLinkS;
unsigned newLimit, i;
voiD D;
if (!linkS || n >= nodes)
return voiD0;
D = linkS[(first+n)%limit];
if (!n) { /* pop */
if (++first >= limit)
first = 0;
}
else if (n != nodes-1) { /* del interior */
/* move front rightward */
memmove(&linkS[first+1],&linkS[first],
sizeof(linkS[0])*n);
first++;
}
if (--nodes == 0)
flags |= BDR_SORTED;
if (n < curNode)
curNode--;
else if (n == curNode)
curNode = nodes;
if (nodes < lowThreshold) {
newLimit = lowLimit;
if ((newLinkS = new voiD[newLimit])
!= voiDV0) {
if ((i = limit - first) > nodes)
i = nodes;
memcpy(newLinkS,&linkS[first],
sizeof(linkS[0])*i);
/* copy wrap around */
if (i < nodes)
memcpy(&newLinkS[i],linkS,
sizeof(linkS[0])
*(nodes-i));
/*
Compute next smaller linkS
size and threshold for
shrinking.
*/
if (lowLimit - delta > delta)
lowLimit -= delta;
else
lowLimit = delta;
lowThreshold = lowLimit - delta;
/* swap new for old */
delete linkS;
linkS = newLinkS;
limit = newLimit;
first = 0;
}
}
Ddetach(D);
return D;
}
int Binder::allDel()
{
if (!linkS)
return 0;
for (unsigned i = 0; i < nodes; /* no reinit */)
if (!atDel(i))
i++;
return (nodes? 0 : 1);
}
int Binder::allFree()
{
if (!linkS)
return 0;
if (flags & BDR_OK_FREE)
for (unsigned i = 0; i < nodes;
/* no reinit */)
if (!Dfree(atDel(i)))
i++;
return (nodes? 0 : 1);
}
voiD Binder::atPut(unsigned n, const voiD D)
{
if (linkS && D && (n < nodes))
if (Dattach(D)) {
flags &= ~BDR_SORTED;
voiD& N = linkS[(first+n)%limit];
Ddetach(N);
DFREE(N);
return (N=D);
}
return voiD0;
}
voiD Binder::atGet(unsigned n)
{
return ((linkS && (n < nodes))?
linkS[(first+n)%limit] : voiD0);
}
voiD Binder::atXchg(unsigned n, const voiD D)
{
if (linkS && D && (n < nodes))
if (Dattach(D)) {
flags &= ~BDR_SORTED;
voiD& N = linkS[(first+n)%limit];
voiD oldD = N;
N = D;
Ddetach(oldD);
return oldD;
}
return voiD0;
}
unsigned Binder::index(const voiD D)
{
unsigned i;
if (linkS && D)
for (i = 0; i < nodes; i++)
if (D == linkS[(first+i)%limit])
return i;
return BDR_NOTFOUND;
}
int Binder::forEach(BDRforEachBlocK B, voiD M, voiD A)
{
unsigned i;
if (!linkS || !B || !nodes)
return 0;
for (i = 0; i < nodes; i++)
(*B)(linkS[(first+i)%limit],M,A);
return 1;
}
unsigned Binder::firstThat(BDRdetectBlocK B, voiD M)
{
unsigned i;
if (linkS && B)
for (i = 0; i < nodes; i++)
if ((*B)(linkS[(first+i)%limit],M))
return i;
return BDR_NOTFOUND;
}
unsigned Binder::lastThat(BDRdetectBlocK B, voiD M)
{
unsigned i;
if (linkS && B && nodes)
for (i = nodes; i--; /* no reinit */)
if ((*B)(linkS[(first+i)%limit],M))
return i;
return BDR_NOTFOUND;
}
int Binder::collect(BDRcollectBlocK B, BindeR R,
voiD M, voiD A)
{
unsigned i;
if (!linkS || !B || !R)
return 0;
for (i = 0; i < nodes; i++)
(*B)(linkS[(first+i)%limit],R,M,A);
return 1;
}
/* FlexList like primitives: */
unsigned Binder::CurNode()
{
return ((curNode < nodes)?
curNode : BDR_NOTFOUND);
}
int Binder::setCurNode(unsigned n)
{
return ((curNode = ((n > nodes)? nodes : n))
< nodes);
}
Binder& Binder::operator<<(Binder& (*manipulator)
(Binder& B))
{
return (manipulator? (*manipulator)(*this)
: *this);
}
voiD Binder::ins(const voiD D)
{
if (atIns(curNode+1,D)) {
if (++curNode >= nodes)
curNode = nodes - 1;
return D;
}
return voiD0;
}
voiD Binder::insSort(